home *** CD-ROM | disk | FTP | other *** search
-
- /***************************************************************************
-
- XMON.C
-
- - 6502 debugger/monitor
-
- 01/30/88 created
-
- 06/26/88 12:40
-
- ***************************************************************************/
-
- #include <stdio.h>
- #include <osbind.h>
- #include "xglobal.h"
- #include "x6502.h"
-
- /* monitor screen size */
- #define XCOMAX 78
- #define YCOMAX 22
- #define MAXBYTE 16
-
- char szCR[] = "\n\r";
-
- char rgchHex[] = "0123456789ABCDEF";
-
- char rgchIn[XCOMAX+2], /* monitor line input buffer */
- rgchOut[XCOMAX+2],
- ch, /* character at rgch[ich] */
- fHardCopy=FALSE; /* if non-zero dumps to printer */
-
- int cchIn, /* cch of buffer */
- ichIn, /* index into buffer character */
- cchOut, /* size of output string */
- hand, /* disk handle */
- fTrace; /* TRUE if trace mode is on */
-
- unsigned int uMemDump = 0, uMemDasm = 0, uMemRun =0;
-
- int fMON=FALSE; /* TRUE if we are in 6502 monitor */
-
- #ifdef LATER
- struct DTA { /* for disk directories */
- char reserved[21] ;
- char attrib ;
- int time, date ;
- long size ;
- char fname[11] ;
- } ioblock ;
-
- struct disk_info {
- long b_free,b_total,b_sec_siz,b_cl_siz ; } diskblock ;
- #endif
-
- extern long mnemonics[] ;
-
- /*********************************************************************/
-
- #ifdef PCREL
- overlay "monitor"
- #endif
-
- outchar(ch)
- char ch ;
- {
- if (ch & 0x80)
- {
- Cconws("\033p");
- Bconout (5,ch & 0x7F);
- Cconws("\033q");
- }
- else
- Bconout (5,ch);
-
- /* check if hardcopy on and printer ready */
- if ((fHardCopy) && (Bconstat(0)))
- Bconout (0,ch) ;
-
- if ((Bconstat(2)!=0) && ((char)(Bconin(2))==' '))
- Bconin(2);
- }
-
- OutPchCch(pch, cch)
- char *pch;
- int cch;
- {
- while (cch--)
- outchar(*pch++);
- }
-
- GetLine()
- {
- register long key; /* return value of Bconin */
- register int wScan, wChar;
-
- cchIn = 0; /* initialize input line cchIngth to 0 */
- Bconout(2,'>');
-
- loop
- {
- key = Bconin(2);
- wChar = (int)key;
-
- #ifdef NEVER
- /* convert to uppercase */
- if (wChar>='a' && wChar<='z')
- wChar -= 32;
- #endif
- /* if it's printable then print it and store it */
- if (wChar>=' ' && wChar < '~')
- {
- Bconout(2,wChar);
- rgchIn[cchIn++] = wChar;
- }
-
- /* if Backspace, delete last char */
- else if (wChar == 8 && cchIn>0)
- {
- Cconws("\b \b");
- cchIn--;
- }
-
- /* Esc clears line */
- else if (wChar == 27)
- {
- Cconws("\033l>");
- cchIn = 0;
- }
-
- #ifdef LATER
- /* if special key, get scan code */
- if (cchIn==0 && ch==0) { /* if special key */
- ch = (char) (key>>16) ; /* get scan code */
- if (ch==0x47) cls() ; /* is it Home? */
- if (ch==0x62) help() ; /* is it Help? */
- break ; /* break out of loop */
- }
- #endif
- /* stay in loop until rgchInfer full or Return pressed */
- if ((cchIn==XCOMAX) || (wChar==13 && cchIn))
- break;
- }
- Cconws(szCR);
- /* terminate input line with a space and null */
- rgchIn[cchIn] = ' ';
- rgchIn[cchIn+1] = 0;
- ichIn = 0;
- }
-
- /* advance ichIn to point to non-space */
- int FSkipSpace()
- {
- char ch;
- while ((ch = rgchIn[ichIn]) == ' ' && ichIn<cchIn)
- ichIn++ ;
- return (ichIn < cchIn);
- }
-
-
- /* returns 0-15 if a valid hex character is at rgchIn[ichIn], else -1 */
- /* returns -2 if character was a space */
- int NextHexChar()
- {
- char ch;
-
- ch = rgchIn[ichIn++];
-
- if (ch>='0' && ch<='9')
- return ch-'0';
- if (ch>='A' && ch<='F')
- return ch-'A'+10;
- if (ch>='a' && ch<='f')
- return ch-'a'+10;
-
- return ((ch == ' ') ? -2 : -1);
- }
-
- /* Get 8 bit value at rgchIn[ichIn]. Returns TRUE if valid number */
- int FGetByte(pu)
- register unsigned *pu;
- {
- register int x;
- int w=0, digit=0 ;
-
- if (!FSkipSpace())
- return FALSE;
- while (((x = NextHexChar()) >= 0) && digit++ < 2)
- {
- w <<= 4 ;
- w += x;
- }
- *pu = w;
- return (x != -1);
- }
-
-
- /* Get 16 bit value at rgchIn[ichIn]. Returns TRUE if valid number */
- int FGetWord(pu)
- register unsigned *pu;
- {
- register int x;
- int w=0, digit=0 ;
-
- if (!FSkipSpace())
- return FALSE;
- while (((x = NextHexChar()) >= 0) && digit++ < 4)
- {
- w <<= 4 ;
- w += x;
- }
- *pu = w;
- #ifdef NDEBUG
- printf("FGetWord(): x = %d returning %d\n", x, (x != -1));
- #endif
- return (x != -1);
- }
-
- mon() /* the 6502 monitor */
- {
-
- int fQuit=0; /* quit flag */
- char chCom; /* command character */
- char ch;
- int cch;
- int digit, cNum, cLines;
- unsigned u1, u2, u3, u4;
- register char *pch;
- #ifdef LATER
- unsigned char header[6];
- #endif
-
- fMON=TRUE;
-
- /* position cursor to bottom of screen, so that the title scrolls off */
- Cconws ("\033E\n 6502 Monitor\n\r\n");
-
- Cursconf(1,0);
- do
- {
- GetLine();
- FSkipSpace(); /* skip any leading spaces */
- chCom = rgchIn[ichIn++] ; /* get command character */
-
- pch = rgchOut;
-
- switch(chCom)
- {
- case ';' : /* comment is ignored */
- break ;
-
- /* X to quit */
- case 'X':
- case 'x':
- fQuit = TRUE;
- break ;
-
-
- /* dump memory */
- case 'M':
- case 'm':
- if (FGetWord(&u1))
- {
- #ifdef NDEBUG
- printf("u1 OK = %4x\n", u1);
- #endif
- uMemDump = u1;
- if (FGetWord(&u2))
- {
- #ifdef NDEBUG
- printf("u1 OK = %4x\n", u1);
- #endif
- u2++;
- }
- else
- u2 = u1 + MAXBYTE;
- }
- else
- {
- u2 = uMemDump + 16*MAXBYTE;
- }
-
- #ifdef NDEBUG
- printf("dump: u1 = %4x u2 = %4x uMemDump = %4x\n",
- u1, u2, uMemDump);
- #endif
- do
- {
- Blitcz(' ', rgchOut, XCOMAX);
- rgchOut[0] = ':';
- rgchOut[57] = '\'';
- XtoPch(&rgchOut[1], uMemDump);
-
- for (cNum=0; cNum<MAXBYTE; cNum++)
- {
- BtoPch(&rgchOut[7 + 3*cNum + (cNum>=MAXBYTE/2)],
- ch = Peek(uMemDump++));
- rgchOut[cNum+58] = ch;
- if (uMemDump == u2)
- break;
- }
- OutPchCch(rgchOut,74);
- Cconws(szCR);
- } while (uMemDump != u2);
- break ;
-
- case 'D':
- case 'd':
- if (FGetWord(&u1))
- uMemDasm = u1;
-
- for (cNum=0; cNum<20; cNum++)
- {
- Blitcz(' ', rgchOut, XCOMAX);
- cch = CchDisAsm(rgchOut, &uMemDasm);
- OutPchCch(rgchOut, cch);
- Cconws(szCR);
- }
- break ;
-
- /* dump/modify registers */
- case 'R':
- case 'r':
- case '.':
- Blitcz(' ', rgchOut, XCOMAX);
- cch = CchShowRegs(rgchOut);
- OutPchCch(rgchOut, cch);
- Cconws(szCR);
- break;
-
- /* set hardcopy on/off flag */
- case 'H':
- case 'h':
- if (FGetByte(&u1))
- fHardCopy = u1;
- break ;
-
- case 'B':
- case 'b':
- ColdStart();
- cch = CchShowRegs(rgchOut);
- OutPchCch(rgchOut, cch);
- Cconws(szCR);
- break ;
-
- case 'G':
- case 'g':
- fTrace = FALSE;
- cLines = 1;
- goto Lgo;
-
- case 'S':
- case 's':
- cLines = 1;
- goto Lstep;
-
- case 'T':
- case 't':
- cLines = 20;
- Lstep:
- fTrace = TRUE;
- Lgo:
- {
- unsigned int u;
-
- if (FGetWord(&u1))
- uMemRun = u1;
-
- while (cLines--)
- {
- Blitcz(' ', rgchOut, XCOMAX);
- u = uMemRun;
- CchDisAsm(rgchOut, &u);
- RunAt(&uMemRun);
- cch = CchShowRegs(rgchOut+32);
- OutPchCch(rgchOut, 32+cch);
- Cconws(szCR);
- }
- }
- break ;
-
- /* modify memory */
- case ':':
- if (!FGetWord(&u1))
- {
- Cconws("invalid address");
- break;
- }
- while (FGetByte(&u2))
- {
- Poke(u1++, u2);
- }
- break;
-
- #ifdef LATER
- case 'M': pc = addr1 ; /* block memory move */
- addr2 = get_addr() ;
- addr3 = get_addr() ;
- while (addr1<=addr2) *(mem+addr3++) = *(mem+addr1++) ;
- break ;
-
- case 'C' : pc = addr1 ; /* block memory compare */
- addr2 = get_addr() ;
- addr3 = get_addr() ;
- while (addr1<=addr2)
- if (*(mem+addr3++) != *(mem+addr1++))
- {
- print(" (");
- showaddr(addr1-1);
- print(") ");
- showhex(addr1-1);
- print(" (");
- showaddr(addr3-1);
- print(") ");
- showhex(addr3-1);
- CR;
- }
- break ;
-
- case ':' :
- pc = addr1 ; /* modify memory */
- FSkipSpace() ;
- while (rgchIn[ichIn] && (ichIn<cchIn))
- {
- *(mem+pc++) = get_byte() ;
- FSkipSpace() ;
- }
- break ;
-
- case 'V' :
- show_emul() ; /* view virtual machine screen */
- getchar() ;
- show_scr() ;
- break ;
- #endif
-
- default :
- Bconout(2,7);
- }
- } while (!fQuit) ;
-
- fMON=FALSE;
- Cursconf(0,0);
- }
-
- void XtoPch(pch, u)
- char *pch;
- unsigned int u;
- {
- *pch++ = rgchHex[(u>>12)&0xF];
- *pch++ = rgchHex[(u>>8)&0xF];
- *pch++ = rgchHex[(u>>4)&0xF];
- *pch++ = rgchHex[u&0xF];
- }
-
- void BtoPch(pch, b)
- char *pch;
- unsigned int b;
- {
- *pch++ = rgchHex[(b>>4)&0xF];
- *pch++ = rgchHex[b&0xF];
- }
-
- ColdStart()
- {
- /* clear all registers */
- PutReg('A',0);
- PutReg('X',0);
- PutReg('Y',0);
- PutReg('P',0xFF);
-
- /* set initial SP = $FF */
- PutReg('SP',0xFF);
-
- uMemRun = 0xFFFC;
- fReboot = FALSE;
- return RunThru(&uMemRun);
- }
-
- Continue()
- {
- if (fReboot)
- return ColdStart();
-
- uMemRun = GetReg('PC');
- return RunAt(&uMemRun);
- }
-
-
- /* end of _XMON.C */
-
-
-